//*********************************************************************** // Monty_Hall.h // // this is an implementation of a puzzle which involves choosing a winning // choice from three possible choices. it is similar to the cunundrum // faced by contestants on "Let's Make A Deal" with Monty Hall - thus // the name Monty_Hall. // // INPUTS: // // OUTPUTS: // //*********************************************************************** // WARNING: none // //*********************************************************************** // IMPLEMENTATION NOTE: all files are in the executable working directory // //*********************************************************************** // created by: j. aleshunas // created on: 22 jun 05 // modified on: 31 oct 05 // // © 2005 John Aleshunas // //*********************************************************************** #include #include #include #include #include #include using namespace std; //*********************************************************************** // class Door declaration //*********************************************************************** class Door { // private class variables // private methods public: // public class variables string sPrize; bool bOpen; // public methods Door(void){ sPrize = "Empty"; bOpen = false; }// constructor }; // class Door //*********************************************************************** // class Simulation_instance declaration //*********************************************************************** class Simulation_instance { // private class variables vector vSim; // the simulation setting int iChoice; int iTries; int iCorrect; int iSwitch_ct; int iMonty_choice; // private methods int Random_value(int iRange); void Initialize_doors(void); void Open_door(int iIndex); void Choose_door(void); void Choose_auto_door(void); void Change_door(void); void Change_auto_door(char cSel); void Show_doors(void); void Montys_choice(void); void Montys_auto_choice(void); public: // public class variables // public methods Simulation_instance(void); // constructor void Run_simulation(void); void Run_auto_simulation(int iIncrement_ct, char cSelection); void Show_results(void); void Reset_stats(void); }; // class Classification_instance //*********************************************************************** // class Simulation_instance method declarations //*********************************************************************** Simulation_instance::Simulation_instance(void) { // local variables Door clDoor_instance; // initialize the local variable clDoor_instance.sPrize = "empty"; clDoor_instance.bOpen = false; // initialize the class variables iChoice = 0; iTries = 0; iCorrect = 0; iSwitch_ct = 0; // load the simulation vector for(int iIndex = 0; iIndex < 3; iIndex++) { vSim.push_back(clDoor_instance); } // for return; } // Simulation_instance::Simulation_instance //*********************************************************************** void Simulation_instance::Run_simulation(void) { // declare the local variables bool bCorrect; // initialize the variables bCorrect = false; // initialize the doors Initialize_doors( ); // increment the tries count iTries++; cout << "==============================================================" << endl; cout << endl << "Here are the doors for you to choose from." << endl << endl; // show the doors Show_doors( ); // get the player's door choice Choose_door( ); // Monty opens a door without a prize Montys_choice( ); // give the player a chance to change doors Change_door( ); // open the player's door choice Open_door(iChoice); // update the results if(vSim[iChoice].sPrize == "Big_Prize") bCorrect = true; if (bCorrect) iCorrect++; // show the doors cout << "==============================================================" << endl; Show_doors( ); cout << endl << endl; if(bCorrect) {cout << "You choose door #" << iChoice + 1 << " and you are a winner!!!"; cout << endl << endl;} else cout << "You choose door #" << iChoice + 1 << " and you are a loser!!!" << endl << endl; return; } // Simulation_instance::Run_simulation //*********************************************************************** void Simulation_instance::Run_auto_simulation(int iIncrement_ct, char cSelection) { // declare the local variables bool bCorrect; int iIndex; for(iIndex = 0; iIndex < iIncrement_ct; iIndex++) { // initialize the variables bCorrect = false; // initialize the doors Initialize_doors( ); // increment the tries count iTries++; // get the player's door choice Choose_auto_door( ); // Monty opens a door without a prize Montys_auto_choice( ); // give the player a chance to change doors Change_auto_door(cSelection); // open the player's door choice Open_door(iChoice); // update the results if(vSim[iChoice].sPrize == "Big_Prize") bCorrect = true; if (bCorrect) iCorrect++; } // while return; } // Simulation_instance::Run_auto_simulation //*********************************************************************** int Simulation_instance::Random_value(int iRange) { // the local variables int iRand_val = 0; int iRand_num = 0; // initialize the PRNG - but only the first time if(iTries < 2) srand( (unsigned)time( NULL ) ); // generate a random value iRand_num = rand(); // generate the return value iRand_val = iRand_num % iRange; return(iRand_val); } // Simulation_instance::Random_value //*********************************************************************** void Simulation_instance::Initialize_doors(void) { // local variables int iIndex; int iPrize_door = 9; // choose the prize door iPrize_door = Random_value(3); // initialize the doors for(iIndex = 0; iIndex < 3; iIndex++) { // randomly place the prize if (iIndex == iPrize_door) vSim[iIndex].sPrize = "Big_Prize"; else vSim[iIndex].sPrize = "Goat"; // ensure that all of the doors are closed vSim[iIndex].bOpen = false; } // for return; } // Simulation_instance::Initialize_doors //*********************************************************************** void Simulation_instance::Open_door(int iIndex) { vSim[iIndex].bOpen = true; return; } // Simulation_instance::Open_door //*********************************************************************** void Simulation_instance::Choose_door(void) { // local variables int iDoor_choice; bool bNot_done = true; // loop until we get a correct door choice while(bNot_done){ // initialize the variable iDoor_choice = 9; // get the user's door choice cout << endl; cout << "Do you want door #1, door #2, or door #3? "; cin >> iDoor_choice; // save the choice if((iDoor_choice > 3)||(iDoor_choice < 0)){ cout << endl << endl << "That is an invalid choice."; } else {iChoice = iDoor_choice - 1; // save the choice bNot_done = false; // exit the loop } cout << endl << endl; } //while return; } // Simulation_instance::Choose_door //*********************************************************************** void Simulation_instance::Choose_auto_door(void) { // local variables // generate a random door choice iChoice = Random_value(3); return; } // Simulation_instance::Choose_auto_door //*********************************************************************** void Simulation_instance::Change_door(void) { // local variables char cAnswer = 'x'; int iNew_choice; // find out whether the user wants to change his door selection cout << endl; cout << "==============================================================" << endl; cout << "Do you want to change your choice? (y/n) "; cin >> cAnswer; cout << endl << endl; if(cAnswer == 'y') { // determine which door wasn't chosen by you or Monty // increment the counter iSwitch_ct++; // calculate the empty door iNew_choice = (3 - iChoice) - iMonty_choice; // save the result iChoice = iNew_choice; } // if return; } // Simulation_instance::Change_door //*********************************************************************** void Simulation_instance::Change_auto_door(char cSel) { // local variables int iNew_choice; if(cSel == 'y') { // determine which door wasn't chosen by you or Monty // increment the counter iSwitch_ct++; // calculate the empty door iNew_choice = (3 - iChoice) - iMonty_choice; // save the result iChoice = iNew_choice; } // if return; } // Simulation_instance::Change_auto_door //*********************************************************************** void Simulation_instance::Show_doors(void) { // local variables int iIndex; // show the doors to the user cout << endl; for(iIndex = 0; iIndex < 3; iIndex++) { cout << "Door number " << (iIndex + 1) << endl; if (vSim[iIndex].bOpen) cout << vSim[iIndex].sPrize << endl; else cout << "The door is closed" << endl; cout << endl; } // for return; } // Simulation_instance::Show_doors //*********************************************************************** void Simulation_instance::Show_results(void) { // local variables float fAccuracy; cout << endl; cout << "==============================================================" << endl; cout << "You have made " << iTries << " tries." << endl; cout << "You have switched doors " << iSwitch_ct << " times." << endl; cout << "You were correct " << iCorrect << " times." << endl; if(iTries >0) fAccuracy = (float)iCorrect / (float)iTries; else fAccuracy = 0; // prevent divide by zero cout << "Your accuracy was " << fAccuracy << endl << endl; return; } // Simulation_instance::Show_results //*********************************************************************** void Simulation_instance::Reset_stats(void) { // reset the class variables iChoice = 0; iTries = 0; iCorrect = 0; iSwitch_ct = 0; return; } // Simulation_instance::Reset_stats //*********************************************************************** void Simulation_instance::Montys_choice(void) { // declare the local variables vector viAvailable_doors; int iIndex, chosen_door; //char cPause; // initialize chosen_door = 99; // pick a door to display - it must not have a prize and isn't the player's door for(iIndex = 0; iIndex < 3; iIndex++) { if((vSim[iIndex].sPrize == "Goat") && (iIndex != iChoice)) viAvailable_doors.push_back(iIndex); } // for // choose the door that Monty will open if(viAvailable_doors.size( ) > 1) chosen_door = viAvailable_doors[Random_value(2)]; else chosen_door = viAvailable_doors[0]; // introduction to opening a door without a prize behind it cout << endl << endl; cout << "==============================================================" << endl; cout << "Before we see what is behind door #" << iChoice + 1 << endl; cout << "Let me show you what is behind door #" << (chosen_door + 1) << endl << endl; // open chosen_door Open_door(chosen_door); // show the doors Show_doors( ); // save the chosen door iMonty_choice = chosen_door; return; } // Simulation_instance::Montys_choice //*********************************************************************** void Simulation_instance::Montys_auto_choice(void) { // declare the local variables vector viAvailable_doors; int iIndex, chosen_door; //char cPause; // initialize chosen_door = 99; // pick a door to display - it must not have a prize and isn't the player's door for(iIndex = 0; iIndex < 3; iIndex++) { if((vSim[iIndex].sPrize == "Goat") && (iIndex != iChoice)) viAvailable_doors.push_back(iIndex); } // for // choose the door that Monty will open if(viAvailable_doors.size( ) > 1) chosen_door = viAvailable_doors[Random_value(2)]; else chosen_door = viAvailable_doors[0]; // open chosen_door Open_door(chosen_door); // save the chosen door iMonty_choice = chosen_door; return; } // Simulation_instance::Montys_auto_choice